package com.handpay.nocardpay.baselibrary.utils;

import android.graphics.Bitmap;
import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.SystemClock;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.style.ForegroundColorSpan;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.ListView;

import com.handpay.nocardpay.baselibrary.NoCardPayApplication;
import com.handpay.nocardpay.baselibrary.commbase.BaseProtocolKey;
import com.handpay.nocardpay.baselibrary.logutils.HPLog;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import java.util.zip.CRC32;

/**
 * @author sxshi on 2016/6/15.
 * @email:emotiona_xiaoshi@126.com
 * @describe:工具包
 */
public class CommonUtils {
    /**
     * 判断给定csn是不是新版刷卡器
     *
     * @param csn
     * @return
     */
    public static boolean isNewSwiper(String csn) {
        // 通过判断csn是不是16进制字符串来决定
        if (TextUtils.isEmpty(csn)) {
            return false;
        } else {
            boolean result = true;
            // csn = csn.toLowerCase(Locale.US);
            // for (int i=0; result && i < csn.length(); i++) {
            // if(-1 == charToByte(csn.charAt(i))) {
            // result = false;
            // }
            // }
            if (csn.startsWith("CMBC")) {
                result = false;
            } else {
                result = true;
            }
            HPLog.i("Main", "isNewSwiper:" + result);
            return result;
        }

    }

    /***
     * @param useIPv4
     * @return 获取IPv4地址
     */
    public static String getIPAddress(boolean useIPv4) {
        try {
            List<NetworkInterface> interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
            for (NetworkInterface intf : interfaces) {
                List<InetAddress> addrs = Collections.list(intf.getInetAddresses());
                for (InetAddress addr : addrs) {
                    if (!addr.isLoopbackAddress()) {
                        String sAddr = addr.getHostAddress();
                        // boolean isIPv4 =
                        // InetAddressUtils.isIPv4Address(sAddr);
                        boolean isIPv4 = sAddr.indexOf(':') < 0;

                        if (useIPv4) {
                            if (isIPv4)
                                return sAddr;
                        } else {
                            if (!isIPv4) {
                                int delim = sAddr.indexOf('%'); // drop ip6 zone
                                // suffix
                                return delim < 0 ? sAddr.toUpperCase() : sAddr.substring(0, delim).toUpperCase();
                            }
                        }
                    }
                }
            }
        } catch (Exception ex) {
        } // for now eat exceptions
        return "";
    }

    /***
     * 错误信息处理
     *
     * @param errMsg
     * @return
     */
    public static String dealWebError(String errMsg) {
        if (errMsg.indexOf("M021") != -1) {
            return errMsg = "账账通开通失败";
        }
        // 显示系统异常，不应该提示用户后台信息
        // return getString(R.string.system_error);
        return errMsg;
    }

    /**
     * 判断是否为最新版本方法 将版本号根据.切分为int数组 比较
     *
     * @param localVersion  本地版本号
     * @param onlineVersion 线上版本号
     * @return true 有新的版本
     */
    public static boolean isAppNewVersion(String localVersion, String onlineVersion) {
        if (localVersion.equals(onlineVersion)) {
            return false;
        }
        String[] localArray = localVersion.split("\\.");
        String[] onlineArray = onlineVersion.split("\\.");
        int length = localArray.length < onlineArray.length ? localArray.length : onlineArray.length;
        for (int i = 0; i < length; i++) {
            if (Integer.parseInt(onlineArray[i]) > Integer.parseInt(localArray[i])) {
                return true;
            } else if (Integer.parseInt(onlineArray[i]) < Integer.parseInt(localArray[i])) {
                return false;
            }
        }
        return true;
    }

    /***
     * 十六进制转换二进制
     *
     * @param hexString
     * @return
     */
    public static byte[] hexStringToBytes(String hexString) {
        if (hexString == null || hexString.equals("")) {
            return null;
        }
        hexString = hexString.toUpperCase(Locale.US);
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
        }
        return d;
    }

    /***
     * byte 转换为16进制
     *
     * @param src
     * @return
     */
    public static String bytesToHexString(byte[] src) {
        if (src == null || src.length <= 0) {
            return null;
        }
        try {
            StringBuilder stringBuilder = new StringBuilder(2 * src.length);
            for (int i = 0; i < src.length; i++) {
                int v = src[i] & 0xFF;
                String hv = Integer.toHexString(v);
                if (hv.length() < 2) {
                    stringBuilder.append(0);
                }
                stringBuilder.append(hv);
            }
            return stringBuilder.toString();
        } catch (Exception outOfMemoryError) {
            HPLog.e("", "bytes length:" + src.length + "outOfMemoryError:" + outOfMemoryError.getMessage());
        }
        return null;
    }

    /*** 10进制串转为BCD码
     * @param asc 10进制串
     * @return BCD码
     */
    public static byte[] str2Bcd(String asc) {
        int len = asc.length();
        int mod = len % 2;
        if (mod != 0) {
            asc = "0" + asc;
            len = asc.length();
        }
        byte abt[] = new byte[len];
        if (len >= 2) {
            len = len / 2;
        }
        byte bbt[] = new byte[len];
        abt = asc.getBytes();
        int j, k;
        for (int p = 0; p < asc.length() / 2; p++) {
            if ((abt[2 * p] >= '0') && (abt[2 * p] <= '9')) {
                j = abt[2 * p] - '0';
            } else if ((abt[2 * p] >= 'a') && (abt[2 * p] <= 'z')) {
                j = abt[2 * p] - 'a' + 0x0a;
            } else {
                j = abt[2 * p] - 'A' + 0x0a;
            }
            if ((abt[2 * p + 1] >= '0') && (abt[2 * p + 1] <= '9')) {
                k = abt[2 * p + 1] - '0';
            } else if ((abt[2 * p + 1] >= 'a') && (abt[2 * p + 1] <= 'z')) {
                k = abt[2 * p + 1] - 'a' + 0x0a;
            } else {
                k = abt[2 * p + 1] - 'A' + 0x0a;
            }
            int a = (j << 4) + k;
            byte b = (byte) a;
            bbt[p] = b;
        }
        return bbt;
    }

    /**
     * 将16进制数字解码成字符串,适用于所有字搜索符（包括中文）
     */
    public static String hex2String(String bytes) {
        String hexString = "0123456789ABCDEF";
        ByteArrayOutputStream baos = new ByteArrayOutputStream(bytes.length() / 2);
        // 将每2位16进制整数组装成一个字节
        for (int i = 0; i < bytes.length(); i += 2)
            baos.write((hexString.indexOf(bytes.charAt(i)) << 4 | hexString.indexOf(bytes.charAt(i + 1))));
        return new String(baos.toByteArray());
    }

    /**
     * 字符串转16进制
     *
     * @param str
     * @return
     */
    public static String string2Hex(String str) {
        char[] chars = str.toCharArray();
        StringBuffer hex = new StringBuffer();
        for (int i = 0; i < chars.length; i++) {
            hex.append(Integer.toHexString((int) chars[i]));
        }
        return hex.toString();
    }

    /***
     *
     * @param plainExpireDate
     * @return
     */
    public static boolean checkExpireDate(String plainExpireDate) {
        if (!TextUtils.isEmpty(plainExpireDate) && plainExpireDate.length() >= 4) {
            return true;
        }
        return false;
    }

    /***
     * 将金额转换为VPOS显示金额
     * @param money
     * @param totalLen
     * @return
     */
    public static String formatMoneyToPos(Double money, int totalLen) {
        HPLog.e("TAG", "money" + money);
        String moneyStr = money.intValue() + "";
        return "0000000000".substring(0, totalLen - moneyStr.length()) + moneyStr;
    }

    /***
     * 将金额转换为VPOS显示金额
     * @param money
     * @param totalLen
     * @return
     */
    public static String formatMoneyToPos(String money, int totalLen) {
        String zero = "";
        for (int i = 0; i < totalLen; i++) {
            zero += "0";
        }
        String moneyStr = money;
        return zero.substring(0, totalLen - moneyStr.length()) + moneyStr;
    }

    /**
     * 格式化金额为12位的,主要是为发往银联的交易 送进来的金额是元的,转成12位之后就是分了 比如商城传来的是50.0元 那么传给银联就是
     * 000000005000
     *
     * @param transAmount
     * @return
     * @author fyang
     */
    public static String formatMoenyToUnionpay(String transAmount) {
        BigDecimal money = new BigDecimal(String.valueOf(transAmount));
        money.multiply(new BigDecimal(100)).intValue();
        String result = "0000000000000" + money.multiply(new BigDecimal(100)).intValue();
        result = result.substring(result.length() - 12);
        return result;
    }

    /**
     * 格式化金额，将20位的银联金额格式变为普通元角分格式。
     *
     * @param amount 需要格式化的金额。
     * @return 格式化后的金额。
     */
    public static final String formatAmount(String amount) {
        String newAmount = new String();

        int len = amount.length();
        int index = -1;
        for (int i = 0; i < len; i++) {
            char c = amount.charAt(i);
            if (c != '0') {
                index = i;
                break;
            }
        }

        if (index == -1)
            return "0.00";

        newAmount = amount.substring(index);
        if (newAmount.length() < 3) {
            newAmount = ("00" + newAmount);
            newAmount = newAmount.substring(newAmount.length() - 3);
        }

        String newAmount0 = newAmount.substring(newAmount.length() - 2);
        String newAmount1 = newAmount.substring(0, newAmount.length() - 2);

        newAmount = newAmount1 + "." + newAmount0;

        return newAmount;
    }

    /**
     * @param c
     * @return
     */
    private static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }

    /***
     * 判断是否是 0-9 a-z(可以用正则表达实现)
     * @param str
     * @return
     */
    public static boolean isNumAndChar(String str) {
        if (TextUtils.isEmpty(str)) {
            return false;
        }
        char[] s = str.toLowerCase(Locale.US).toCharArray();
        boolean hasDigit = false;
        boolean hasChar = false;
        boolean hasOther = false;
        for (int i = 0; i < s.length; i++) {
            if ('0' <= s[i] && '9' >= s[i]) {
                hasDigit = true;
                continue;
            }
            if ('a' <= s[i] && 'z' >= s[i]) {
                hasChar = true;
                continue;
            }
            hasOther = true;
            break;
        }
        return hasDigit && hasChar && !hasOther;
    }

    /**
     * 将float类型的人民币数字格式化为保留两位小数的字符串
     *
     * @param money
     * @return
     */
    public static String formatMoneyDouble(double money) {
        DecimalFormat df = new DecimalFormat("0.00");
        return df.format(money);
    }

    /***
     *
     * @param time
     * @return 格式化之后的时间
     */
    public static String formatTime(String time) {
        String year = "";
        String mm = "";
        String day = "";
        String hh = "";
        String ff = "";
        String ms = "";
        if (!TextUtils.isEmpty(time)) {
            year = time.substring(0, 4);
            mm = time.substring(4, 6);
            day = time.substring(6, 8);
            hh = time.substring(8, 10);
            ff = time.substring(10, 12);
            ms = time.substring(12, 14);
        }
        return year + "/" + mm + "/" + day + "  " + hh + ":" + ff + ":" + ms;
    }

    /***
     *
     * @param time
     * @return
     */
    public static String formatYearMMDay(String time) {
        String year = "";
        String mm = "";
        String day = "";
        if (!TextUtils.isEmpty(time)) {
            year = time.substring(0, 4);
            mm = time.substring(4, 6);
            day = time.substring(6, 8);
        }
        return year + "/" + mm + "/" + day;
    }

    public static AdapterView.OnItemClickListener createNoQuickResponseViewListener(final int noResponseTime, final AdapterView.OnItemClickListener listener) {
        return new AdapterView.OnItemClickListener() {
            private long mLastClickTime = 0;

            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                // TODO 自动生成的方法存根
                // 避免多次点击
                if (SystemClock.elapsedRealtime() - mLastClickTime < noResponseTime) {
                    return;
                }
                mLastClickTime = SystemClock.elapsedRealtime();
                listener.onItemClick(parent, view, position, id);
            }
        };
    }

    /***
     * 动态计算ListView的高度
     * @param listView
     */
    public static void setListViewHeightBasedOnChildren(ListView listView) {
        // 获取ListView对应的Adapter
        ListAdapter listAdapter = listView.getAdapter();
        if (listAdapter == null) {
            return;
        }
        int totalHeight = 0;
        for (int i = 0, len = listAdapter.getCount(); i < len; i++) { // listAdapter.getCount()返回数据项的数目
            View listItem = listAdapter.getView(i, null, listView);
            listItem.measure(0, 0); // 计算子项View 的宽高
            totalHeight += listItem.getMeasuredHeight(); // 统计所有子项的总高度
        }
        ViewGroup.LayoutParams params = listView.getLayoutParams();
        params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
        // listView.getDividerHeight()获取子项间分隔符占用的高度
        // params.height最后得到整个ListView完整显示需要的高度
        listView.setLayoutParams(params);
    }

    /***
     * @param object
     * @return object 转换为String
     */
    public static String objectToString(Object object) {
        if (object == null) return null;
        if (object != null) {
            if (object instanceof Double) {
                return String.valueOf(((Double) object).doubleValue());
            } else if (object instanceof String) {
                return (String) object;
            } else if (object instanceof Integer) {
                return String.valueOf(((Integer) object).intValue());
            } else if (object instanceof Float) {
                return String.valueOf(((Float) object).floatValue());
            }
            return object.toString();
        }
        return null;
    }

    /***
     * @param object
     * @return
     */
    public static int objectToInt(Object object) {
        if (object == null) return -1;
        try {
            if (object instanceof Double) {
                return ((Double) object).intValue();
            } else if (object instanceof String) {
                return Integer.valueOf(object.toString());
            } else if (object instanceof Integer) {
                return (Integer) object;
            } else if (object instanceof Float) {
                return ((Float) object).intValue();
            }
        } catch (ClassCastException e) {
            return -1;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return -1;
    }

    /***
     * @param object
     * @return
     */
    public static Double objectToDouble(Object object) {
        if (object == null) return 0.0d;
        if (object instanceof Double) {
            return (Double) object;
        } else if (object instanceof String) {
            return Double.valueOf(object.toString());
        } else if (object instanceof Integer) {
            return ((Integer) object).doubleValue();
        } else if (object instanceof Float) {
            return ((Float) object).doubleValue();
        }
        return 0.0d;
    }

    public static int dp2px(float dpValue) {
        return (int) (dpValue * Heart.density + 0.5f);
    }

    public static int px2dp(float pxValue) {
        return (int) (pxValue / Heart.density + 0.5f);
    }

    /**
     * 替换、过滤特殊字符
     */
    public static String StringFilter(String str) throws PatternSyntaxException {
        str = str.replaceAll("【", "[").replaceAll("】", "]").replaceAll("！", "!").replaceAll("，", ",").replaceAll("&", "\n");//替换中文标号
        String regEx = "[『』]"; // 清除掉特殊字符
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(str);
        return m.replaceAll("").trim();
    }

    /**
     * 格式化金额  以千分符  1000,000,00.00
     *
     * @param mMoney
     * @return
     */
    public static String formatMoneyWithSplite(Double mMoney) {
        BigDecimal loanAmount = new BigDecimal(mMoney);
        NumberFormat currency = NumberFormat.getNumberInstance();
        currency.setMaximumFractionDigits(2);
        currency.setMinimumFractionDigits(2);
        return currency.format(loanAmount);
    }


//    public static String formatMoney(Double mMoney) {
//        NumberFormat nf = NumberFormat.getNumberInstance();
//        nf.setMaximumFractionDigits(2);
//        return nf.format(mMoney);
//    }


    public static Uri randomUri(File directory) {
        Uri uri = Uri.fromFile(randomFile(directory));
        return uri;
    }

    public static File randomFile(File directory) {
        File file;
        Random r = new Random();
        long rand = r.nextLong();
        do {
            file = new File(directory, "pic" + rand + ".jpg");
            rand++;
        } while (file.exists());
        return file;
    }

    public static boolean removePics() {
        File folder = getAccessDir();
        for (File f : folder.listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String filename) {
                HPLog.i("removePics", "accept filename:" + filename);
                return filename.startsWith("pic") && filename.endsWith("jpg");
            }
        })) {
            f.delete();
        }
        return true;
    }

    public static File getAccessDir() {
        // FIXME 判断在外部存储还是内部存储。
        String strStorageState = android.os.Environment.getExternalStorageState();
        if (android.os.Environment.MEDIA_MOUNTED.equals(strStorageState)) {
            File f = Environment.getExternalStorageDirectory();
            File picDir = new File(f.getAbsolutePath() + File.separator + BaseProtocolKey.Dir_NAME);
            if (picDir.exists()) {
                return picDir;
            } else {
                // 如果创建目录成功，返回该目录，否则返回SDK根目录
                if (picDir.mkdirs()) {
                    return picDir;
                } else {
                    return f;
                }
            }
        } else {
            return NoCardPayApplication.getApp().getApplicationContext().getFilesDir().getAbsoluteFile();
        }

    }

    /**
     * 格式化手机号码
     *
     * @param phone 手机号码
     * @return 返回格式化之后的手机号码
     */
    public static String formatPhoneNumber(String phone) {
        String start = phone.substring(0, 3);
        String end = phone.substring(phone.length() - 4);
        return start + " **** " + end;
    }

    /**
     * 将float类型的人民币数字格式化为带￥且保留两位小数的字符串
     *
     * @param money
     * @return
     */
    public static String formatMoney(double money) {
        DecimalFormat df = new DecimalFormat("0.00");
        return "¥" + df.format(money);
    }

    /**
     * 格式化銀行卡 如：**** **** **** 5678
     *
     * @param card
     * @return
     */
    public static String formattingCard(String card) {
        if (TextUtils.isEmpty(card)) {
            return null;
        }
        StringBuffer sb = new StringBuffer();
        card = card.replace(" ", "");
        int index = 0;
        String start = card.substring(index, index + 4);
        String end = card.substring(card.length() - 4);
        return "**** **** ****" + " " + end;
    }

    /**
     * 将日期按照格式化为指定格式字符串
     *
     * @param date
     * @param pattern
     * @return
     */
    public static String formatDateToString(Date date, String pattern) {
        if (date == null) {
            return null;
        }
        SimpleDateFormat sdf = (SimpleDateFormat) SimpleDateFormat
                .getInstance();
        sdf.applyPattern(pattern);
        return sdf.format(date);
    }

    /**
     * 时间格式化
     *
     * @param dateString
     * @param pattern
     * @return
     */
    public static Date formatStringToDate(String dateString, String pattern) {
        if (TextUtils.isEmpty(dateString))
            return null;
        SimpleDateFormat sdf = (SimpleDateFormat) SimpleDateFormat
                .getInstance();
        sdf.applyPattern(pattern);
        try {
            return sdf.parse(dateString);
        } catch (ParseException e) {
            HPLog.e("format error", "format " + dateString
                    + " to date by yyyyMMddHHmmss throw exception!!");
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @param startDate
     * @param endDate
     * @return
     */
    public static boolean equalsDate(Date startDate, Date endDate) {
        int startday = startDate.getDate();
        int endday = endDate.getDate();
        int startmoth = startDate.getMonth() + 1;
        int endmoth = endDate.getMonth() + 1;
        int Intervalday = 0;
        if (!startDate.after(endDate)) {
            if (endDate.getYear() - startDate.getYear() == 0
                    || endDate.getYear() - startDate.getYear() == 1) {
                Log.i("result", "endmoth=" + endmoth + ",startmoth="
                        + startmoth);
                if (endmoth - startmoth <= 1) {
                    if (endmoth - startmoth == 1 || endmoth - startmoth == -11) {// 不在同一个月
                        // 开始月剩下的天数
                        int tempstartdata = getday(startDate.getYear(),
                                startmoth) - startday;
                        Log.i("result", "tempstartdata=" + tempstartdata);
                        Log.i("result", (tempstartdata + endday) + "");
                        return tempstartdata + endday <= 30;
                    } else {
                        // 同一个月
                        return !(endDate.getYear() - startDate.getYear() != 0
                                || endday - startday > getday(
                                startDate.getYear(), startmoth));
                    }
                } else {
                    return false;
                }
            } else {
                if (endDate.getYear() - startDate.getYear() == 1) {
                    return startday + endday <= 30;
                } else {
                    return false;
                }
            }
        } else {
            return false;
        }
    }

    /**
     * 获取天数
     *
     * @param year
     * @param curr_moth
     * @return
     */
    private static int getday(int year, int curr_moth) {
        int allday = 0;
        switch (curr_moth) {
            case 1:
            case 3:
            case 5:
            case 7:
            case 8:
            case 10:
            case 12:
                allday = 31;
                break;
            case 2:
                allday = get2Days(year);
                break;
            default:
                allday = 30;
                break;
        }
        return allday;
    }

    private static int get2Days(int year)// 计算某一年2月份有多少天
    {
        Calendar c = Calendar.getInstance();
        c.set(year, 2, 1);// 0-11->1-12 将日期设置为某一年的3月1号
        c.add(Calendar.DAY_OF_MONTH, -1);// 将日期减去一天，即日期变成2月的最后一天
        return c.get(Calendar.DAY_OF_MONTH);// 返回二月最后一天的具体值
    }

    /**
     * 根据日历获取当前日期字符串
     *
     * @param calendar
     * @param pattern
     * @return
     */
    public static String currentDate(Calendar calendar, String pattern) {
        SimpleDateFormat sdf = (SimpleDateFormat) SimpleDateFormat.getInstance();
        sdf.applyPattern(pattern);
        return sdf.format(calendar.getTime());
    }

    /**
     * 改变字体颜色
     *
     * @param text
     * @param startIndex
     * @param endIndex
     * @return
     */
    public static SpannableString changeTextColor(String text, int startIndex, int endIndex) {
        SpannableString spanString = new SpannableString(text);
        ForegroundColorSpan span = new ForegroundColorSpan(Color.rgb(93, 140, 184));
        spanString.setSpan(span, startIndex, endIndex, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
        return spanString;
    }


    /**
     * 根据给定的Bitmap,返回byte数组。
     *
     * @param cache
     * @param max   限定byte数组大小。单位为KB
     * @return
     */
    public static byte[] getBitmapBytes(Bitmap cache, int max) {
        int maxByte = max * 1024;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        cache.compress(Bitmap.CompressFormat.JPEG, 99, baos);
        byte[] b = baos.toByteArray();
        try {
            baos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (b.length <= maxByte) {
            return b;
        }
        // 原图超过最大限定，压缩到固定比例传
        int rate = (int) (Math.sqrt((maxByte * 1.0d) / b.length) * 100); // 这个方法并不确保一定比max小
        baos = new ByteArrayOutputStream();
        cache.compress(Bitmap.CompressFormat.JPEG, rate, baos);
        b = baos.toByteArray();
        try {
            baos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return b;
    }

    public static File getAutoExistFile(File directory, String fileName) {
        File file = new File(directory, fileName);
        return file;
    }

    public static String getCRC(CRC32 crc, byte[] bytes) {
        if (null == crc) {
            return "";
        }
        crc.reset();
        crc.update(bytes);
        return String.valueOf(crc.getValue());
    }


    /**
     * --判断卡号是否合法
     *
     * @param cardNo
     * @return
     */
    public static boolean isLegalCard(String cardNo) {
        String tempCardNo = cardNo;
        tempCardNo = tempCardNo.trim();
        tempCardNo = tempCardNo.replace(" ", "");
        if (TextUtils.isEmpty(tempCardNo) || tempCardNo.length() < 11) {
            return false;
        }
        char[] cCardNo = tempCardNo.toCharArray();
        boolean allZero = true;
        for (int j = 0; j < cCardNo.length; j++) {
            if ('0' != cCardNo[j]) {
                allZero = false;
                break;
            }
        }
        // 全零，不是合法卡号
        if (allZero) {
            return false;
        }
        return true;
    }

    /***
     * 检验手机号码是否合法
     * @param mobiles
     * @return
     */
    public static boolean isMobileNum(String mobiles) {
        if (mobiles == null || mobiles.trim().length() == 0){
            return false;
        }
        if (mobiles.length() != 11) {
            return false;
        }
        if (!isMobileNO1(mobiles)) {
            return false;
        }
        return '1' == mobiles.charAt(0);
    }

    public static boolean isMobileNO1(String mobiles) {
        String regExp = "^[1][0-9]{10}$";
        Pattern p = Pattern.compile(regExp);
        Matcher m = p.matcher(mobiles);
        return m.matches();
    }

    public static String formattingCertNo4_2(String certNo) {
        if (TextUtils.isEmpty(certNo)) {
            return null;
        }
        String start = certNo.substring(0, 4);
        String end = certNo.substring(certNo.length() - 2);
        return start + "************" + end;
    }

    /***
     * 验证用户名的正确性 包含.的输入
     *
     * @param regNameEx
     * @return
     */
    public static boolean isRealName(String regNameEx) {
        if (TextUtils.isEmpty(regNameEx)) return false;
        if (regNameEx.contains("·")) {
            //包含特殊字符"·"
            Pattern p = Pattern.compile("^[\\u4e00-\\u9fa5]{1,10}(?:·[\\u4e00-\\u9fa5]{1,10})*$");
            Matcher m = p.matcher(regNameEx);
            return m.find();
        } else {
            //未包含特殊字符"·"，2~5个汉字
            Pattern p = Pattern.compile("^[\\u4e00-\\u9fa5]{2,10}$");
            Matcher m = p.matcher(regNameEx);
            return m.find();
        }
    }
    /*********************************** 身份证验证开始 ****************************************/
    /**
     * 身份证号码验证 1、号码的结构 公民身份号码是特征组合码，由十七位数字本体码和一位校验码组成。排列顺序从左至右依次为：六位数字地址码，
     * 八位数字出生日期码，三位数字顺序码和一位数字校验码。 2、地址码(前六位数）
     * 表示编码对象常住户口所在县(市、旗、区)的行政区划代码，按GB/T2260的规定执行。 3、出生日期码（第七位至十四位）
     * 表示编码对象出生的年、月、日，按GB/T7408的规定执行，年、月、日代码之间不用分隔符。 4、顺序码（第十五位至十七位）
     * 表示在同一地址码所标识的区域范围内，对同年、同月、同日出生的人编定的顺序号， 顺序码的奇数分配给男性，偶数分配给女性。 5、校验码（第十八位数）
     * （1）十七位数字本体码加权求和公式 S = Sum(Ai * Wi), i = 0, ... , 16 ，先对前17位数字的权求和
     * Ai:表示第i位置上的身份证号码数字值 Wi:表示第i位置上的加权因子 Wi: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4
     * 2 （2）计算模 Y = mod(S, 11) （3）通过模得到对应的校验码 Y: 0 1 2 3 4 5 6 7 8 9 10 校验码: 1 0
     * X 9 8 7 6 5 4 3 2
     */
    public static final String[] ValCodeArr = {"1", "0", "x", "9", "8", "7", "6", "5", "4", "3", "2"};
    public static final String[] Wi = {"7", "9", "10", "5", "8", "4", "2", "1", "6", "3", "7", "9", "10", "5", "8", "4", "2"};
    // 身份证的最小出生日期,1900年1月1日
    private final static int NEW_CARD_NUMBER_LENGTH = 18;

    /**
     * 功能：身份证的有效验证
     *
     * @param IDStr        身份证号
     * @param isValidate15 是否需要校验15位身份证
     * @return 有效：返回null 无效：返回String信息
     * @throws ParseException
     */
    public static String IDCardValidate(String IDStr, boolean isValidate15) throws ParseException {
        IDStr = IDStr.toLowerCase(Locale.US);

        String Ai = "";
        // ================ 号码的长度 15位或18位 ================
        if ((isValidate15 == false ? true : IDStr.length() != 15) && IDStr.length() != 18) {
            return isValidate15 == true ? "身份证号码长度应该为15位或18位。" : "身份证号码长度应该为18位。";
        }
        // else{//如果是15位旧身份证，则根据算法补全
        // if(IDStr.length()==15){
        // IDStr=contertToNewCardNumber(IDStr);
        // }
        // }
        // =======================(end)========================

        // ================ 数字 除最后以为都为数字 ================
        if (IDStr.length() == 18) {
            Ai = IDStr.substring(0, 17);
        } else if (IDStr.length() == 15) {
            Ai = IDStr.substring(0, 6) + "19" + IDStr.substring(6, 15);
        }
        if (isNumeric(Ai) == false) {
            return "身份证15位号码都应为数字 ; 18位号码除最后一位外，都应为数字。";
        }
        // =======================(end)========================

        // ================ 出生年月是否有效 ================
        String strYear = Ai.substring(6, 10);// 年份
        String strMonth = Ai.substring(10, 12);// 月份
        String strDay = Ai.substring(12, 14);// 月份
        if (DateUtils.isDate(strYear + "-" + strMonth + "-" + strDay) == false) {
            return "身份证生日无效。";
        }
        GregorianCalendar gc = new GregorianCalendar();
        SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd");
        if ((gc.get(Calendar.YEAR) - Integer.parseInt(strYear)) > 150 || (gc.getTime().getTime() - s.parse(strYear + "-" + strMonth + "-" + strDay).getTime()) < 0) {
            return "身份证生日不在有效范围。";
        }
        if (Integer.parseInt(strMonth) > 12 || Integer.parseInt(strMonth) == 0) {
            return "身份证月份无效";
        }
        if (Integer.parseInt(strDay) > 31 || Integer.parseInt(strDay) == 0) {
            return "身份证日期无效";
        }
        // =====================(end)=====================

        // ================ 地区码时候有效 ================
        Hashtable<String, String> h = GetAreaCode();
        if (h.get(Ai.substring(0, 2)) == null) {
            return "身份证地区编码错误。";
        }
        // ==============================================

        // ================ 判断最后一位的值 ================
        int TotalmulAiWi = 0;
        for (int i = 0; i < 17; i++) {
            TotalmulAiWi = TotalmulAiWi + Integer.parseInt(String.valueOf(Ai.charAt(i))) * Integer.parseInt(Wi[i]);
        }
        int modValue = TotalmulAiWi % 11;
        String strVerifyCode = ValCodeArr[modValue];
        Ai = Ai + strVerifyCode;

        if (IDStr.length() == 18) {
            if (Ai.equals(IDStr) == false) {
                return "身份证无效，不是合法的身份证号码";
            }
        } else {
            return null;
        }
        // =====================(end)=====================
        return null;
    }

    /**
     * 功能：设置地区编码
     *
     * @return Hashtable 对象
     */
    private static Hashtable<String, String> GetAreaCode() {
        Hashtable<String, String> hashtable = new Hashtable<String, String>();
        hashtable.put("11", "北京");
        hashtable.put("12", "天津");
        hashtable.put("13", "河北");
        hashtable.put("14", "山西");
        hashtable.put("15", "内蒙古");
        hashtable.put("21", "辽宁");
        hashtable.put("22", "吉林");
        hashtable.put("23", "黑龙江");
        hashtable.put("31", "上海");
        hashtable.put("32", "江苏");
        hashtable.put("33", "浙江");
        hashtable.put("34", "安徽");
        hashtable.put("35", "福建");
        hashtable.put("36", "江西");
        hashtable.put("37", "山东");
        hashtable.put("41", "河南");
        hashtable.put("42", "湖北");
        hashtable.put("43", "湖南");
        hashtable.put("44", "广东");
        hashtable.put("45", "广西");
        hashtable.put("46", "海南");
        hashtable.put("50", "重庆");
        hashtable.put("51", "四川");
        hashtable.put("52", "贵州");
        hashtable.put("53", "云南");
        hashtable.put("54", "西藏");
        hashtable.put("61", "陕西");
        hashtable.put("62", "甘肃");
        hashtable.put("63", "青海");
        hashtable.put("64", "宁夏");
        hashtable.put("65", "新疆");
        hashtable.put("71", "台湾");
        hashtable.put("81", "香港");
        hashtable.put("82", "澳门");
        hashtable.put("91", "国外");
        return hashtable;
    }

    /**
     * 功能：判断字符串是否为数字
     *
     * @param str
     * @return
     */
    private static boolean isNumeric(String str) {
        Pattern pattern = Pattern.compile("[0-9]*");
        Matcher isNum = pattern.matcher(str);
        return isNum.matches();
    }


    /**
     * 获取url参数Map
     *
     * @param url
     * @return
     */
    public static Map<String, String> getUrlParamsMap(String url) {
        Map<String, String> map = null;
        if (url != null) if (url.indexOf("?") > -1) {
            url = url.substring(url.indexOf("?") + 1);
        }
        if (url.indexOf("&") > -1 && url.indexOf("=") > -1) {
            map = new HashMap<>();
            String[] arrTemp = url.split("&");
            for (String str : arrTemp) {
                String[] qs = str.split("=");
                map.put(qs[0], qs[1]);
            }
        }
        return map;
    }

}
